package marks

import (
	"errors"
	"fmt"
	"github.com/ipfs/go-ipfs-api"
	"net"
	"os"
	"time"
)

var URL = "127.0.0.1"
var PORT = 5001

type Shell struct {
	api *shell.Shell
	Chain *HashChain
	Owner string
}

func NewShell(path ,Owner string) *Shell {
	if ConnTest(){
		return &Shell{
			api: shell.NewLocalShell(),
			Chain:NewHashChain(path),
			Owner:Owner,
		}
	}
	return nil

}

func (this *Shell) Add(path string ,describe string) (string, error) {
	var cid string
	var obj = &Object{}
	if path == "" || this == nil {
		return "", errors.New("path or shell is nil")  //判断路径是否为空
	}
	cid, e := this.api.AddDir(path)  //调用ifps add api
	if e != nil {
		return "", e
	}
	e, ft := SpiltFileName(path)   //文件名切分
	if e != nil {
		return "", e
	}

	if ft != FL {                  //文件夹或文件类型判断
			if this.Chain.LastObj == nil {
				obj = NewObject("", path, cid, describe,this.Owner)
			} else {
				obj = NewObject(this.Chain.LastObj.Cid, path, cid, describe,this.Owner)
			}
	}else{
		if this.Chain.LastObj == nil {
			obj = NewObject("", path, cid, describe,this.Owner)
		} else {
			obj = NewObject(this.Chain.LastObj.Cid, path, cid, describe,this.Owner)
		}
	}
	err := this.Chain.Add(BucketName, []byte(cid), obj)

	if err != nil {
		if err == errors.New("this object exist already don't add again"){
			return cid, nil
		}
		return "", err
	} else {
		return cid, nil
	}
}


func (this *Shell) View(hash string) (*Object, error) {
	if this == nil || hash == "" {
		return nil, errors.New("can't empty")
	} else {
		bytes, e := this.Chain.Db.View([]byte("test"), []byte(hash))
		if e != nil {
			return nil, e
		} else {
			obj := &Object{}
			if UnSerialize(bytes, obj) {
				return obj, nil
			}

		}
	}
	return nil, errors.New("unserialize fail")
}

func (this *Shell) Get(hash string,outdir... string)bool {
	if this == nil || hash == "" {
		return false
	}else{
		object, e := this.View(hash)
		if e != nil{
			return false
		}
		if len(outdir) == 0{
			e = this.api.Get(string(object.Cid), string(object.PathName))
			if e != nil {
				return false
			}
		}else {
			_, e := os.Stat(outdir[0])
			if e != nil{
				e = os.Mkdir(outdir[0],0666)
				if e != nil{
					fmt.Println(e)
					return false
				}
			}

			dir := fmt.Sprintf("%s/%s",outdir[0],object.PathName)
			e = this.api.Get(string(object.Cid),dir)
			if e != nil {
				return false
			}
		}


	}
	return true
}

func ConnTest() bool {
	_, e := net.DialTimeout("tcp", "127.0.0.1:5001", time.Second*5)
	if e != nil {
		panic(e)
		return false
	}else {
		return true
	}

}

